﻿$(function () {
    var datepicker = $('.form_datetime').data('datetimepicker');

    function checkInDates() {
        var edit_flag = sessionStorage.getItem("edit");
        if (edit_flag === "1") {
            var dates = datepicker._markedDates;
            var removeMarkDates = datepicker._removeMarkedDates;
            post_mark_date(dates, removeMarkDates);
        }
    };

    /**
     * 实现将所有选定的日期post回服务器，并根据服务器返回结果重置sessionStorage
     * @param markDates 日期字符串数组
     * @param removeMarkDates 要移除的日期字符串数组
     */
    function post_mark_date(markDates, removeMarkDates) {
        var data = {
            _csrf: $("meta[name=x-csrf-token]").attr("content"),
            markDates: JSON.stringify(markDates),
            removeMarkedDates: JSON.stringify(removeMarkDates)
        }
        $.post('/user/overtime_update', data, function (data, status) {
            var data_obj = JSON.parse(data);
            if (data_obj["code"] === 200) {
                clearSessionStorage();
                showModal("系统提示", "保存成功！");
            } else {
                showModal("错误信息", data.data);
            }
        }).error(function (jxr, status, msg) {
            showModal("系统错误", "保存失败!\r\n错误信息:<" + jxr.status + ">" + msg);
        });
    };
    /**
     * 重置sessionStorage的内容
     */
    function clearSessionStorage() {
        sessionStorage.setItem("edit", "0");
        sessionStorage.removeItem("mark_dates");
        sessionStorage.removeItem("removedMarkDates");
        sessionStorage.removeItem("queryed_months");
    };
    /**
     * 将登记的加班日期和车费合并成一个数组
     * @param markDates
     * @param fares
     */
    function combine_dates_fares(markDates, fares) {
        if (markDates.length != fares.length) { return alter('加班日期和车费设置不匹配!'); }
        var rst = []
        markDates.forEach(function (v, i, ar) {
            rst.push([v, fares[i]]);
        });
        return rst;
    }
    /**
     * 将回合的加班日期和车费拆分出2个独立数组
     * @param mix
     */
    function separe_dates_fares(mix) {
        var markDates = [],
            fares = []
        mix.forEach(function (v, i, ar) {
            markDates.push(v[0]);
            fares.push(v[1]);
        });
        return { markDates: markDates, fares:fares };
    };
    /**
     * 把变更信息同步到sessionStorage并刷新备注历史信息
     * @param dp datepicker控件
     */
    function save_mark_modify_to_sStorage(dp) {
        sessionStorage.setItem("mark_dates", JSON.stringify(dp._markedDates));
        sessionStorage.setItem("removedMarkDates", JSON.stringify(dp._removeMarkedDates));
        build_memo_lst(dp.date.getMonth() + 1); //刷新备注历史信息
    };
    /**
     * 记录新选的日期到保存列表
     * @param dp 日历选择控件
     * @param date 新选的日期本地格式字符串
     * @param money 备注的报销车费
     * @param memo 备注信息
     * @param removeIdx 需要从删除列表中移除项的序列号
     */
    function push_new_mark_date(dp,date,money,memo,removeIdx) {
        dp._markedDates.push([date, money, memo]);
        // 从删除项缓存中移除点击的日期
        if (removeIdx >= 0) { dp._removeMarkedDates.splice(removeIdx, 1); }
        dp.fill();
        // 同步到sessionStorage
        save_mark_modify_to_sStorage(dp);
    };
    /**
     * 按照模板重写备注历史
     */
    function build_memo_lst(target_month) {
        let ls_it_tplt = "<li>#{date}#\t-\t#{fare}# #{memo}#</li>",
            datas = datepicker._markedDates,
            container = $('ul.memo');
        container.children('li').remove();
        container.children('h4').remove();
        container.append('<h4>#{month}#月份备注历史</h4>'.replace(/#{month}#/g, target_month));
        datas = datas.filter(function (v) {
            return new Date(v[0]).getMonth() + 1 == target_month;
        })
            .sort(function (a, b) { return new Date(a[0]).valueOf() - new Date(b[0]).valueOf(); });
        datas.forEach(function (v, i) {
            let date = new Date(v[0]),
                fare = v.length > 1 ? v[1] || 0 : 0,
                memo = v.length > 2 ? v[2] || '' : '',
                it_htm = ls_it_tplt;
            if (date.getMonth() + 1 == target_month) {
                if (fare != 0 || memo != '') {
                    it_htm = it_htm.replace(/#{date}#/g, v[0]);
                    if (fare != 0) { it_htm = it_htm.replace(/#{fare}#/g, "车费:" + fare + "&#65509;"); }
                    else { it_htm = it_htm.replace(/#{fare}#/g, ""); }
                    if (memo != '') { it_htm = it_htm.replace(/#{memo}#/g, "备注:" + memo); }
                    else { it_htm = it_htm.replace(/#{memo}#/g, ""); }
                    container.append(it_htm);
                }
            }
        });
    };
    /**
     * 验证money输入是否正确，正确返回true，不正确返回false
     * @param money_elem money的input控件对象
     * @param err_msg 不正确时的警示信息
     */
    function money_validate(money_elem,err_msg) {
        let money = money_elem.val();
        if(!money.match(/^\d{1,}[.]?\d*$/)){
            let gp = money_elem.closest(".form-group");
            if (!gp[0].classList.contains('has-error')) { gp.addClass('has-error'); }
            gp.children('span').remove();
            //if (gp.children("span").length > 0) { err_msg = "；" + err_msg }
            gp.append("<span class='alert-danger'>" + err_msg + "</span>");
            return false;
        }
        return true;
    }
    /**
     * 实现未获取到成功保存消息时，读取本地暂存的选定时间集合
     * 保存成功情况下，读取服务器返回的结果集
     */
    if (parseInt(sessionStorage.getItem("edit")) || 0) {
        if (sessionStorage.getItem("mark_dates") && sessionStorage.getItem("mark_dates") != "undefined") {
            datepicker._markedDates = JSON.parse(sessionStorage.getItem("mark_dates"));
            datepicker.fill();
            build_memo_lst(datepicker.date.getMonth() + 1);
        }
        if (sessionStorage.getItem("removedMarkDates") && sessionStorage.getItem("removedMarkDates") != "undefined") {
            datepicker._removeMarkedDates = JSON.parse(sessionStorage.getItem("removedMarkDates"));
        }
    } else {
        clearSessionStorage();
        var data = {
            _csrf: $("meta[name=x-csrf-token]").attr("content"),
            curr_month: datepicker.date.getMonth() + 1
        };
        $.post('/user/overtime_get', data, function (data, status) {            
            var data_obj = JSON.parse(data);
            if (data_obj["code"] === 200) {
                var rdata = data_obj.data || [];
                sessionStorage.setItem("queryed_months",JSON.stringify([datepicker.date.getMonth() + 1]));
                sessionStorage.setItem("mark_dates", JSON.stringify(rdata));
                datepicker._markedDates = rdata;
                datepicker.fill();
                build_memo_lst(datepicker.date.getMonth() + 1);
            }
        });
    }

    /**
     * 绑定事件响应，实现多日期选定及选定时间本地暂存
     * ===============================================
     * 设计:
     * 1.点击含义的筛选：
     * a.当picker缓存的_markedDates字段中没有点击的日期时，则点击意味着选中日期
     * b.当picker缓存的_markedDates字段中没有点击的日期时:
     * b.1.如果车费选框勾选，则点击意味着添加车费信息
     * b.2.如果车费选框未勾选，则点击意味着取消日期的选择。
     */
    $('.form_datetime').bind("markDate", function (e) {
        sessionStorage.setItem("edit", "1");     
        let idx = separe_dates_fares(datepicker._markedDates).markDates.indexOf(e.date),
            removeIdx = datepicker._removeMarkedDates.indexOf(e.date),
            checkFare = $("input#fare").is(':checked');
        if (idx < 0) {
            if (checkFare) {
                showInputModal('请输入：',
                    [{ lable: '报销车费:', name: "input_fare" },
                        { lable: '备注:', name: "input_memo", dom_type: "textarea" }],
                    function () {
                        /**
                         * todo : 输入money校验
                         */
                        let money = $('#alertInputDlg .modal-body form').find("input#input_fare").val(),
                            memo = $('#alertInputDlg .modal-body form').find("textarea#input_memo").val();
                        if (money != "") {
                            if (!money_validate($('#alertInputDlg .modal-body form').find("input#input_fare"),"车费输入有误!")) { return;}
                        }
                        push_new_mark_date(datepicker, e.date, money, memo, removeIdx);
                        $(this).parents().find("#alertInputDlg").modal('hide');
                    }
                );
            } else {
                push_new_mark_date(datepicker, e.date, null, null, removeIdx);
            }          
        } else {
            if (!checkFare) {
                datepicker._markedDates.splice(idx, 1);
                datepicker._removeMarkedDates.push(e.date);
                datepicker.fill(); // 因为控件click触发fill时，还没更改_markedDates值，所以要重新fill一下
                save_mark_modify_to_sStorage(datepicker);
            } else {
                showInputModal('请输入：',
                    [{ lable: '报销车费:', name: "input_fare", value: datepicker._markedDates[idx][1]},
                        { lable: '备注:', name: "input_memo", dom_type: "textarea", value: datepicker._markedDates[idx][2]}],
                    function () {
                        /**
                         * todo : 输入money校验
                         */
                        let money = $('#alertInputDlg .modal-body form').find("input#input_fare").val(),
                            memo = $('#alertInputDlg .modal-body form').find("textarea#input_memo").val();
                        if (money != "") {
                            if (!money_validate($('#alertInputDlg .modal-body form').find("input#input_fare"), "车费输入有误!")) { return; }
                        }
                        datepicker._markedDates[idx][1] = money;
                        datepicker._markedDates[idx][2] = memo;
                        save_mark_modify_to_sStorage(datepicker);
                        $(this).parents().find("#alertInputDlg").modal('hide');
                    }
                );
            }
        }        
    });

    /**
     * 绑定事件相应，当月份发生改变时
     * 1.如果目标月不在已读取数据的范围内，则请求后台当目标月数据
     * 2.更新已读取后台数据的月份信息
     */
    $('.form_datetime').bind("changeMonth", function (e) {
        let target_month = e.date.getMonth() + 1,
            data = {
                _csrf: $("meta[name=x-csrf-token]").attr("content"),
                curr_month: target_month
            },
            queryed_months = JSON.parse(sessionStorage.getItem("queryed_months")) || [];
        if (queryed_months.indexOf(target_month) >= 0) {
            build_memo_lst(target_month);
            return;
        }
        $.post('/user/overtime_get', data, function (data) {
            let rdata = JSON.parse(data).data || [],
                pre_marked_data = datepicker._markedDates || [];                
            rdata = rdata.concat(pre_marked_data);
            queryed_months.push(target_month);
            sessionStorage.setItem("mark_dates", JSON.stringify(rdata));
            sessionStorage.setItem("queryed_months", JSON.stringify(queryed_months));
            datepicker._markedDates = rdata;
            datepicker.fill();
            build_memo_lst(target_month);
        }).error(function (jxr, status, msg) {
            showModal("系统错误", "错误信息:<" + jxr.status + ">" + msg);
        });
    });

    /**
     * 实现离开页面前(不包括页面刷新)保存数据到数据库
     */
    $(window).unload(checkInDates);

    $('div#save.btn').on("click", checkInDates);
});